import axios from "axios";

export class ZhipuSDK {
  /**
   * 构造函数
   * 初始化HTTP客户端，用于与API服务器进行通信
   * @param {Object} options - 包含API密钥的配置对象
   */
  constructor(options) {
    this.client = axios.create({
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${options.apiKey}`,
      },
      baseURL: "https://open.bigmodel.cn/api/paas/v4",
      // 启用跨域请求中的凭证携带
      withCredentials: true,
    });
  }

  /**
   * 异步创建补全功能
   *
   * 本函数通过POST请求与服务器通信，以生成基于给定消息的补全响应
   * 它支持流式处理，可以通过回调函数实时处理生成的数据
   *
   * @param {Object} options - 包含补全请求配置的选项对象
   * @param {Object} handlers - 包含处理生成数据的回调函数的对象，默认为空对象
   * @returns {Promise<Object>} - 返回一个Promise，解析为补全响应数据
   */
  async createCompletions(options, handlers = {}) {
    try {
      // 发起请求
      const response = await this.client({
        method: "POST",
        url: "/chat/completions",
        responseType: options.stream ? "stream" : "json",
        data: {
          model: options.model,
          messages: options.messages,
          stream: !!options.stream,
        },
      });

      // 如果不是流式处理，直接返回响应数据
      if (!options.stream) {
        handlers.onProgress?.(response.data);
        return response.data;
      }

      // 初始化处理流式响应的变量
      let unhandledMessage = ""; // 未处理的消息
      let deltaContent = ""; // 增量内容
      let lastResponse; // 最后响应

      // 处理流式响应数据
      for await (const chunk of response.data) {
        const messages = (unhandledMessage + chunk.toString()).split("\n");
        unhandledMessage = "";

        for (const message of messages) {
          // 如果消息不以data:开头，则将消息添加到未处理的消息中
          if (!message.startsWith("data:")) {
            unhandledMessage += message;
            continue;
          }

          // 如果消息是[DONE]，则调用onProgressEnd回调函数，并继续处理下一个消息
          if (message === "data: [DONE]") {
            handlers.onProgressEnd?.(lastResponse);
            continue;
          }

          try {
            // 如果消息不以}结尾，则将消息添加到未处理的消息中
            if (!message.endsWith("}")) {
              unhandledMessage += message;
              continue;
            }

            // 解析消息
            const json = JSON.parse(message.replace("data: ", ""));

            // 如果流式处理方式为append，则将增量内容添加到json中
            if (options.stream === "append") {
              deltaContent += json.choices[0].delta.content;
              json.choices[0].message = deltaContent;
            }

            // 将最后响应设置为json
            lastResponse = json;

            // 调用onProgress回调函数，并传递json
            handlers.onProgress?.(json);
          } catch (error) {
            // 如果解析消息失败，则将消息添加到未处理的消息中
            unhandledMessage += message;
          }
        }
      }

      // 返回最后响应
      return lastResponse;
    } catch (error) {
      // 如果发生错误，则打印错误信息
      console.error("ZhipuSDK Error:", error.response?.data || error.message);
      throw error;
    }
  }
}
